require 'htree'
require 'rexml/document'
require 'open-uri'
require 'iconv'
#http://redhanded.hobix.com/inspect/noXpathOnMessyHtmlIsJustAsEasyInRuby.html

class NzbController < ApplicationController
  before_filter :authenticate_member
  before_filter :authenticate_admin, :except => ['search', 'download', 'upload']

  def cancel_download
    Hellanzb.instance.cancel
    redirect_to :back
  end

  def dequeue
    Hellanzb.instance.dequeue(params['id'])
    redirect_to :back
  end

  def queue_down
    Hellanzb.instance.down(params[:id])
    redirect_to :back
  end
  def queue_up
    Hellanzb.instance.up(params['id'])
    redirect_to :back
  end


  def search
    if params[:media_id] && @media = Media.find(params[:media_id])
      binsearch_url = "https://www.binsearch.info/?q=#{CGI::escape(@media.fichier)}&max=250&adv_age=600&server="
      unless( @results = wrap_binsearch(binsearch_url))
          binsearch_url << '2'
	  @server = 2
          @results = wrap_binsearch(binsearch_url)
      end
      render :layout => false
    end
  end

  
  def download
    if Hellanzb.instance.is_connected?
    if params[:media_id] && media = Media.find(params[:media_id])
      nzb_ids = Array.new
      params.each do |param| # lol trick de dingue, sale code
        id = param[0].to_i
        nzb_ids.push(id) if(id && id > 0)
      end
      if(nzb_ids.empty?)
        flash[:notice] = 'Erreur : vous devez choisir au moins un fichier/collection !'
        redirect_to :back
      else
        http = Net::HTTP.new('www.binsearch.info');
	req_uri = '/fcgi/nzb.fcgi'
	req_uri << '?server=2' if params[:server]=='2'
        data = 'action=nzb&'
        data << nzb_ids.join('=on&')
	resp, data = http.post(req_uri, data)
        if resp.code.to_i == 200
          nzb_filename = Iconv.conv('ASCII//IGNORE', 'UTF-8', media.nom.strip.gsub(/\//,'-'))
          nzb_filename = "#{nzb_filename}_#{media.id}"
          nzb_file = HELLA_NZB_QUEUE + '/' + nzb_filename + '.nzb'
          nzb_filepath = String.new(nzb_file)
          if resp['content-disposition'].include?('nzb.gz')
            nzb_filepath << '.gz'
            has_to_be_uncompressed = true
          end
          if nzb = File.new(nzb_filepath, 'w')
            puts "write to #{nzb_filepath}" if DEBUG
            nzb.syswrite(data)
            nzb.close_write
            `gunzip -f "#{nzb.path}"` if has_to_be_uncompressed
            Hellanzb.instance.enqueue(nzb_file)
            media.nzb_id = Hellanzb.instance.get_nzb_id_from_name(nzb_filename)
            FileUtils.rm(nzb_file)
            media.local_path = nzb_filename
	    media.score = 15
            media.taille = ''
            media.user_id = session[:user].id
            media.save
            flash[:notice] = 'Le nzb a bien été téléchargé. Vous pouvez compléter les infos le concernant!cimer'
            redirect_to edit_media_path(media)
          else
            flash[:notice] = 'Cannot write nzb file!'
            redirect_to :back
          end
        else
          flash[:notice] = 'An error occured while trying to retrieve NZB!'
          redirect_to :back
        end
      end
    else
      flash[:notice] = 'Erreur : aucun média spécifié!'
      redirect_to :back
    end
    else
      flash[:notice] = 'Erreur : le client newsgroup est stoppé. Impossible de lancer un nouveau téléchargement!'
      redirect_to :back
    end
  end

  def upload
    if(params[:file] && (params[:file].kind_of? ActionController::UploadedFile) && params[:categ] && categ = Category.find(params[:categ]))
        medianame = sanitize_filename(params[:file].original_filename).gsub(/\.nzb$/i,'')
        @media = Media.new(:nom => medianame, :category_id => categ.id, :user_id => session[:user].id, :img_src => nil, :score => 15)
        if @media.save
          filename = "#{medianame}_#{@media.id}"
          nzb_file = "#{HELLA_NZB_QUEUE}/#{filename}.nzb"
          if nzb = File.new(nzb_file, 'w')
            nzb.syswrite(params[:file].read)
            nzb.close_write
            flash[:notice] = 'Le nzb a bien été uploadé! Vous êtes invité à renseigner les détails le concernant !'
            @media.local_path = filename
            Hellanzb.instance.enqueue(nzb_file)
            @media.nzb_id = Hellanzb.instance.get_nzb_id_from_name(filename)
            if @media.save
              redirect_to :controller => "medias", :action => "edit", :id => @media
		return
            else
              flash[:notice] = 'Erreur : impossible de sauvegarder le chemin local du media!'
            end
          else
            flash[:notice] = 'Erreur : impossible d\'enqueuter le nouveau nzb !'
          end
        else
            flash[:notice] = 'Erreur : impossible de créer le nouveau média!'
      end
    else
      flash[:notice] = "Erreur : Impossible de valider le fichier nzb envoyé!"
    end
	redirect_to '/'
  end

  private

  #renvoi la page correspondante en REXML::Document avec <html> comme root
  # @param binsearch url
  # @return
  def wrap_binsearch(binsearch_url)
      open(binsearch_url) { |f| HTree.parse f }.each_child do |child|
        if child.respond_to? :qualified_name
          doc = "";child.display_xml( doc )
          if child.qualified_name == 'html'
            html_doc = REXML::Document.new( doc )
            return html_doc.elements["//table[@id='r2']"]
          end
        end
      end
  end

end
